#ifndef BASECMD_H
#define BASECMD_H


#include <QObject>
#include <QDebug>
#include <serializer.h>
#include <parser.h>
#include <serializer.h>
//#include "Encrypt/SM4Encrypt.h"
#include "Encrypt/Encrypt.h"
#include "DataType/Package.h"
#include "DataType/DataType.h"
#include "System/DataTypeConver.h"
//#include "System/System.h"

class BaseCmd : public QObject
{
    Q_OBJECT
public:

    explicit BaseCmd(QObject *parent = 0):QObject(parent)
    {
        m_protocolType = 0;
        m_cmdId = 0;
        m_isHaveCmdId = false;
        m_functionCode = 0;
        m_isEncrypt = false;
        m_isDecrypt = false;
        m_isResend = false;
        m_reSendCount = 0;
        m_timeoutCount = 0;
        m_currentTimeoutCount = 0;
    }
    virtual ~BaseCmd(){}


    virtual Package toPackage() = 0;
    virtual void unPackage(Package package) = 0;

    quint16 cmdId() const
    {
        return this->m_cmdId;
    }
    void setCmdId(const quint16 &cmdId)
    {
        this->m_isHaveCmdId = true;
        this->m_cmdId = cmdId;
    }

    int functionCode() const
    {
        return this->m_functionCode;
    }

    bool isResend() const
    {
        return this->m_isResend;
    }
    void setIsResend(bool isResend)
    {
        this->m_isResend = isResend;
    }

    quint8 reSendCount() const
    {
        return this->m_reSendCount;
    }
    void setReSendCount(const quint8 &reSendCount) 
    {
        this->m_reSendCount = reSendCount;
    }

    quint32 timeoutCount() const
    {
        return this->m_timeoutCount;
    }
    void setTimeoutCount(const quint32 &timeoutCount)
    {
        this->m_timeoutCount = timeoutCount;
    }


    quint32 currentTimeoutCount() const
    {
        return this->m_currentTimeoutCount;
    }
    void setCurrentTimeoutCount(const quint32 &currentTimeoutCount)
    {
        this->m_currentTimeoutCount = currentTimeoutCount;
    }

    bool isHaveCmdId() const
    {
        return m_isHaveCmdId;
    }


    bool isEncrypt() const
    {
        return m_isEncrypt;
    }

    void setIsEncrypt(bool isEncrypt)
    {
        m_isEncrypt = isEncrypt;
    }
    bool isDecrypt() const
    {
        return m_isDecrypt;
    }

    void setIsDecrypt(bool isDecrypt)
    {
        m_isDecrypt = isDecrypt;
    }

    quint8 protocolType() const
    {
        return m_protocolType;
    }

    void setProtocolType(const quint8 &protocolType)
    {
        m_protocolType = protocolType;
    }

protected:
    quint8 m_protocolType;

    quint16 m_cmdId;
    bool m_isHaveCmdId;
    quint32 m_functionCode;

    bool m_isEncrypt;
    bool m_isDecrypt;

    bool m_isResend;
    quint8  m_reSendCount;
    quint32 m_timeoutCount;
    quint32 m_currentTimeoutCount;

    QByteArray encrypt(const QByteArray &data, KeyType::KeyType keyType)
    {
        QByteArray encryptData;
        if(!m_isEncrypt)
        {
            encryptData = data;
        }
        else
        {
            Encrypt *encrypt = Encrypt::getInstance();
            if(keyType == KeyType::AES)
            {
                encryptData = encrypt->aesEncrypt(data);

            }
            else if(keyType == KeyType::RSA)
            {
                encryptData = encrypt->rsaEncrypt(data);
            }
            else if(keyType == KeyType::M4)
            {

               // SM4Encrypt *sm4=SM4Encrypt::getInstance();
              //  encryptData= sm4->Encrypt(data);
               /* qDebug()<<"QByteArray encrypt   KeyType:M4";
                System *system = System::getInstance();
                QMap<QString,QMetaObject>  deviceMetaMap = system->getDeviceMetaMap();
                if(!deviceMetaMap.contains("WXTPlatformDevice"))
                {
                    qDebug()<<"Error:WXTPlatformDevice is not exist!";
                    return 0;
                }
                 qDebug()<<"QByteArray encrypt11   KeyType:M4";
                QMetaObject meta = deviceMetaMap.value("WXTPlatformDevice");
                 qDebug()<<"QByteArray encrypt22   KeyType:M4";
                QMetaObject::invokeMethod((QObject*)&meta,"messageEncrypt");
                 qDebug()<<"QByteArray encrypt33   KeyType:M4";*/

            }
        }
        return encryptData;
    }

    QByteArray decrypt(const QByteArray &data, KeyType::KeyType keyType)
    {
        QByteArray decryptData;
        if(!m_isDecrypt)
        {
            decryptData = data;
        }
        else
        {
            Encrypt *encrypt = Encrypt::getInstance();
            if(keyType == KeyType::AES)
            {
                decryptData = encrypt->aesDecrypt(data);
            }
        }
        return decryptData;
    }
};
Q_DECLARE_METATYPE(QSharedPointer<BaseCmd>)

#endif // BASICCMD_H

